home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Development / Source / MultiSession 1.04 Source / Core 27⁄June⁄1993 / Debug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-26  |  5.6 KB  |  212 lines  |  [TEXT/KAHL]

  1. /* Debug.c */
  2.  
  3. #include "Debug.h"
  4. #include "MiscInfo.h"
  5. #include "Memory.h"
  6.  
  7. /* debugging function, use it to present message */
  8. #define MAINWINDOWCOORDS  70,40,512-70,342-120
  9. #define TEXTBOXCOORDS  8,24,512-70-70-8,342-120-40-8
  10. #define RESUMEBUTTONCOORDS  8,342-120-40-8-20,96+8,342-120-40-8
  11. #define QUITBUTTONCOORDS  120,342-120-40-8-20,96+128,342-120-40-8
  12. /* if AbortFlag == True, then it is impossible to recover from error and */
  13. /* the application must be forced to quit */
  14. /* 'Message' is a C-String [null terminated] */
  15. #define EmergencyCacheSize (4096)
  16.  
  17. static Handle        Emergency;
  18.  
  19. static void (*ErrorFunction)(void) = NIL; /* when system error occurs, call this */
  20.  
  21. #if __option(mc68020)
  22.     #define CodeFor68020
  23. #else
  24.     #define CodeFor68000
  25. #endif
  26. #pragma options(!mc68020) /* this code works no matter what */
  27.  
  28.  
  29. /* conditionally defined range checking procedures */
  30. #ifdef DEBUG
  31. void            HRNGCHK(void* TheHandle, void* EffectiveAddress, signed long AccessSize)
  32.     {
  33.         signed long            HSize;
  34.         signed long            Difference;
  35.  
  36.         StackSizeTest();
  37.         HSize = HandleSize((Handle)TheHandle);
  38.         Difference = (char*)EffectiveAddress - *(Handle)TheHandle;
  39.         if ((Difference < 0) || (Difference + AccessSize > HSize))
  40.             {
  41.                 PRERR(ForceAbort,"Handle access out of range.");
  42.             }
  43.     }
  44.  
  45. void            PRNGCHK(void* ThePointer, void* EffectiveAddress, signed long AccessSize)
  46.     {
  47.         signed long            PSize;
  48.         signed long            Difference;
  49.  
  50.         StackSizeTest();
  51.         PSize = PtrSize((Ptr)ThePointer);
  52.         Difference = (char*)EffectiveAddress - (Ptr)ThePointer;
  53.         if ((Difference < 0) || (Difference + AccessSize > PSize))
  54.             {
  55.                 PRERR(ForceAbort,"Pointer access out of range.");
  56.             }
  57.     }
  58. #endif
  59.  
  60. pascal void        MyResumeProc(void)
  61.     {
  62.         if (ErrorFunction != NIL)
  63.             {
  64.                 (*ErrorFunction)();
  65.             }
  66.         ExitToShell(); /* abort immediately */
  67.     }
  68.  
  69.  
  70. void        SetErrorFunction(void (*Erf)(void))
  71.     {
  72.         ErrorFunction = Erf;
  73.     }
  74.  
  75.  
  76. void        PRERR(short AbortFlag, void* Message)
  77.     {
  78.         WindowRecord    ErrorWindow;
  79.         Rect                    Bounds;
  80.         Rect                    TextRect;
  81.         EventRecord        MyEvent;
  82.         WindowPtr            WhichWindow;
  83.         ControlHandle    ResumeButton;
  84.         ControlHandle    QuitButton;
  85.         ControlHandle    WhichOne;
  86.         long                    NumChars;
  87.         short                    CommandKeyDown;
  88.  
  89.         CheckHeap();
  90.         StackSizeTest();
  91.         if (Emergency != NIL)
  92.             {
  93.                 DisposHandle(Emergency);
  94.                 Emergency = NIL;
  95.             }
  96.         APRINT(("+PRERR: '%t'",Message));
  97.         #ifdef ALWAYSRESUME
  98.             AbortFlag = AllowResume; /* while we're debugging, we can resume */
  99.         #endif
  100.         SetRect(&Bounds,MAINWINDOWCOORDS);
  101.         NewWindow(&ErrorWindow,&Bounds,"\p",True,1,(void*)-1,False,0);
  102.         SelectWindow((WindowPtr)&ErrorWindow);  /* force it to be on top */
  103.         SetRect(&Bounds,RESUMEBUTTONCOORDS);
  104.         ResumeButton = NewControl((WindowPtr)&ErrorWindow,&Bounds,
  105.             "\pResume",True,0,0,0,pushButProc,0);
  106.         SetRect(&Bounds,QUITBUTTONCOORDS);
  107.         QuitButton = NewControl((WindowPtr)&ErrorWindow,&Bounds,
  108.             "\pQuit",True,0,0,0,pushButProc,0);
  109.         if (AbortFlag == ForceAbort)
  110.             {
  111.                 HiliteControl(ResumeButton,255);  /* make it inactive */
  112.             }
  113.         FlushEvents(everyEvent,0);
  114.         while (True)
  115.             {
  116.                 GetNextEvent(everyEvent,&MyEvent);
  117.                 CommandKeyDown = ((MyEvent.modifiers & cmdKey) != 0);
  118.                 switch (MyEvent.what)
  119.                     {
  120.                         case mouseDown:
  121.                             GlobalToLocal(&MyEvent.where);
  122.                             if (FindControl(MyEvent.where,(WindowPtr)&ErrorWindow,&WhichOne) != 0)
  123.                                 {
  124.                                     if (WhichOne != NIL)
  125.                                         {
  126.                                             if (WhichOne == QuitButton)
  127.                                                 {
  128.                                                     if (TrackControl(QuitButton,MyEvent.where,NIL) != 0)
  129.                                                         {
  130.                                                             if (ErrorFunction != NIL)
  131.                                                                 {
  132.                                                                     (*ErrorFunction)(); /* call error function */
  133.                                                                 }
  134.                                                             APRINT(("-PRERR: abort"));
  135.                                                             ENDAUDIT();
  136.                                                             if (CommandKeyDown)
  137.                                                                 {
  138.                                                                     goto SkipBrk1Point;
  139.                                                                 }
  140.                                                             #ifdef THINKC_DEBUGGER
  141.                                                                 #ifdef DEBUG
  142.                                                                     Debugger(); /* break point */
  143.                                                                 #endif
  144.                                                             #endif
  145.                                                          SkipBrk1Point:
  146.                                                             ExitToShell(); /* exit from the program */
  147.                                                         }
  148.                                                 }
  149.                                             if (WhichOne == ResumeButton)
  150.                                                 {
  151.                                                     if (TrackControl(ResumeButton,MyEvent.where,NIL) != 0)
  152.                                                         {
  153.                                                             goto ExitPoint;
  154.                                                         }
  155.                                                 }
  156.                                         }
  157.                                 }
  158.                             break;
  159.                         case updateEvt:
  160.                             BeginUpdate((WindowPtr)&ErrorWindow);
  161.                             SetPort(&ErrorWindow.port);
  162.                             TextFont(0);  /* system font */
  163.                             TextFace(0);  /* normal */
  164.                             TextMode(srcOr);
  165.                             TextSize(12);  /* 12 point */
  166.                             SpaceExtra(0);  /* no extra space */
  167.                             MoveTo(8,16);
  168.                             DrawString("\pA Program Error Occurred:");
  169.                             SetRect(&TextRect,TEXTBOXCOORDS);
  170.                             /* finding length of message string */
  171.                             NumChars = 0;
  172.                             while ( ((char*)Message)[NumChars] != 0)
  173.                                 {
  174.                                     NumChars += 1;
  175.                                 }
  176.                             TextBox(Message,NumChars,&TextRect,teJustLeft);
  177.                             DrawControls((WindowPtr)&ErrorWindow);
  178.                             EndUpdate((WindowPtr)&ErrorWindow);
  179.                             break;
  180.                         default:
  181.                             break;
  182.                     }
  183.             }
  184.      ExitPoint:
  185.         CloseWindow((WindowPtr)&ErrorWindow);
  186.         APRINT(("-PRERR"));
  187.         GetNextEvent(activMask,&MyEvent); /* clear activate event for underlying window */
  188.         if (CommandKeyDown)
  189.             {
  190.                 goto SkipBrk2Point;
  191.             }
  192.         #ifdef THINKC_DEBUGGER
  193.             #ifdef DEBUG
  194.                 Debugger(); /* break point */
  195.             #endif
  196.         #endif
  197.      SkipBrk2Point:
  198.         return;
  199.     }
  200.  
  201. EXECUTE(static MyBoolean    Inited = False;)
  202. void    InitPRERR(void)
  203.     {
  204.         ERROR(Inited,PRERR(ForceAbort,"InitPRERR called more than once."));
  205.         Emergency = NewHandle(EmergencyCacheSize);
  206.         EXECUTE(Inited = True;)
  207.     }
  208.  
  209. #ifdef CodeFor68020
  210.     #pragma options(mc68020) /* turn it back on if necessary */
  211. #endif
  212.